{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit Foregrounds;

interface

uses Classes, Canvas, UIObjects, Fills, Bitmaps, XMLHelper;

{$IFDEF DESIGNER}
const
  // Property categories and hints for designer
  CAT_FOREGROUND = 'Foreground';
  HINT_TYPE = 'defines the type of foreground (Bitmap or Fill)';
  HINT_FILL = 'specifies the name of a fill item to use for the foreground';
  HINT_BITMAP = 'specifies the name of a bitmap item to use for the foreground';
{$ENDIF}

type
  TAHMForegroundType = (ftNone, ftBitmap, ftFill);

  TAHMForeground = class(TAHMUIDisplayObject)
  private
    FType: TAHMForegroundType;
    FFill: TAHMAbstractFill;
    FBitmap: TAHMBitmap;
  protected
    procedure SetFill(Fill: TAHMAbstractFill);
    procedure SetBitmap(Bitmap: TAHMBitmap);
    procedure ClearProperties; override;
  public
    constructor Create(const Name: String); override;
    function RenderPreview: Boolean; override;
    procedure Render(Control: TObject; iX, iY, iWidth, iHeight: Single); override;
    procedure Assign(Source: TPersistent); override;
    procedure SaveXMLBody(Lines: TStrings); override;
    procedure ParseFromXML(XML: TAHMXMLHelper); override;
    procedure BuildProperties(Properties: TAHMUIPropertyList); override;
  published
    property ForegroundType: TAHMForegroundType read FType write FType;
    property Fill: TAHMAbstractFill read FFill write SetFill;
    property Bitmap: TAHMBitmap read FBitmap write SetBitmap;
  end;

  TAHMForegroundList = class(TAHMUIObjectList)
  private
  protected
  public
    constructor Create; override;
    function AddForeground(const InheritFrom, NewName: String): TAHMForeground;
    function GetForeground(const Name: String): TAHMForeground;
  end;


implementation

uses SysUtils, ApplicationManager, TagNames, XMLTags, Viewport, BaseControls,
     Logging, AHMTypes;

constructor TAHMForegroundList.Create;
begin
  inherited Create;

  XMLTagName := TAG_FOREGROUNDS;
  ChildClass := TAHMForeground;
end;

function TAHMForegroundList.AddForeground(const InheritFrom, NewName: String): TAHMForeground;
begin
  Result := TAHMForeground(Inherit(InheritFrom, NewName));
end;

function TAHMForegroundList.GetForeground(const Name: String): TAHMForeground;
begin
  Result := TAHMForeground(GetObject(Name));
end;


//----------------------------------------------------------------------------//
constructor TAHMForeground.Create(const Name: String);
begin
  inherited Create(Name);

  XMLTagName := TAG_FOREGROUND;
  ObjectType := otForegrounds;
  ImageIndex := Ord(otForegrounds);
  PreviewEditable := False;
end;

procedure TAHMForeground.SetFill(Fill: TAHMAbstractFill);
begin
  FFill := Fill;
  if Assigned(Fill) then FType := ftFill;
end;

procedure TAHMForeground.SetBitmap(Bitmap: TAHMBitmap);
begin
  FBitmap := Bitmap;
  if Assigned(Bitmap) then FType := ftBitmap;
end;

function TAHMForeground.RenderPreview: Boolean;
begin
  // Use fullscreen preview of fill foreground
  PreviewFullscreen := FType <> ftBitmap;
  Result := inherited RenderPreview;
end;

procedure TAHMForeground.ClearProperties;
begin
  inherited;

  // Clear custom foreground properties
  FType := ftNone;
  FFill := nil;
  FBitmap := nil;
end;

procedure TAHMForeground.Render(Control: TObject; iX, iY, iWidth, iHeight: Single);
begin
  // Adjust foreground width & height to match container dimensions
  with Control as TAHMAbstractControl do
  begin
    Self.Width := Width;
    Self.Height := Height;
  end;

  // Pre-render our control if necessary
  inherited;

  // Render appropriate foreground content
  if (FType = ftBitmap) and Assigned(FBitmap) then
    FBitmap.Render(Control)
  else if (FType = ftFill) and Assigned(FFill) then
    FFill.Render(Control);
end;

procedure TAHMForeground.Assign(Source: TPersistent);
begin
  inherited Assign(Source);

  with Source as TAHMForeground do
  begin
    Self.ForegroundType := ForegroundType;
    Self.Fill := Fill;
    Self.Bitmap := Bitmap;
  end;
end;

procedure TAHMForeground.SaveXMLBody(Lines: TStrings);
var
  oAncs: TAHMForeground;
begin
  // Determine which ancestor to compare against - real or empty
  oAncs := TAHMForeground(ObjectToCompare);

  // Only populate attributes that differ from our ancestor
  if (FType <> ftNone) and (FType <> oAncs.ForegroundType) then
  begin
    if (FType = ftBitmap) and (FBitmap <> nil) and (FBitmap <> oAncs.Bitmap) then
      Lines.Add(TABS[3] + FBitmap.XMLReference)
    else if (FType = ftFill) and (FFill <> nil) and (FFill <> oAncs.Fill) then
      Lines.Add(TABS[3] + FFill.XMLReference);
  end;
end;

procedure TAHMForeground.ParseFromXML(XML: TAHMXMLHelper);
var
  sName: String;
  ForeNode, PropsNode: TAHMXMLNode;
begin
  // Initialise parsing nodes
  ForeNode := XML.CurrentNode;
  PropsNode := nil;

  // We support a number of foreground types - only expect one element here
  while XML.NextElement(ForeNode, PropsNode) do
    with ApplicationManagerInstance.ThemeManager.VisualDescriptor do
    begin
      // All foreground types have a name attribute
      sName := XML.GetAttribute(ATTR_NAME);

      if (XML.CurrentElement = TAG_FILL) or
         (XML.CurrentElement = TAG_GRADEDFILL) or
         (XML.CurrentElement = TAG_LINEARFILL) then
        Fill := FillList.GetFill(sName)
      else if XML.CurrentElement = TAG_BITMAP then
        Bitmap := BitmapList.GetBitmap(sName);
    end;
end;

procedure TAHMForeground.BuildProperties(Properties: TAHMUIPropertyList);
begin
{$IFDEF DESIGNER}
  inherited;

  // Build custom foreground properties
  Properties.Add('Type', 'ForegroundType', CAT_FOREGROUND, HINT_TYPE);
  Properties.Add('Fill', 'Fill', CAT_FOREGROUND, HINT_FILL);
  Properties.Add('Bitmap', 'Bitmap', CAT_FOREGROUND, HINT_BITMAP);
{$ENDIF}
end;

end.
